home *** CD-ROM | disk | FTP | other *** search
/ AP Professional Graphics CD-ROM Library / AP Professional Graphics CD-ROM Library.iso / pc / unix / appendix / gemsiii / luminair / sphrlumi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-05  |  1.6 KB  |  56 lines

  1. // ******************************************************************
  2. //
  3. // Physically Correct Direct Lighting For Distribution Ray Tracing
  4. //             by Changyaw Wang
  5. //
  6. // sphere_luminaire.c
  7. //
  8. // ******************************************************************
  9.  
  10. #include "utility.h"
  11.  
  12. #ifndef PI
  13. #define PI        3.14159265358979323846
  14. #endif
  15.  
  16. // Selects a point visible from x given (r1,r2).  
  17. // Here, visible means not SELF-shadowed.
  18.  
  19. void sphere::select_visible_point(
  20.              const point& x,   // viewpoint
  21.              const double r1,  // random number
  22.              const double r2,  // random number
  23.              point& on_light,  // point corresponding to (r1,r2)
  24.              double& prob)     // probability of selecting on_light
  25. {
  26.    rotation_matrix m;
  27.    double theta, phi, theta_max;
  28.    vector v1, v2, u, v, w, t, psi;
  29.  
  30.    theta_max = asin(radius/distance(x,center));
  31.    theta = acos(1.0 - r1 + r1 * cos(theta_max)); 
  32.    phi   = 2.0 * PI * r2;
  33.    psi  = spherical_to_vector(theta,phi);
  34.    w = center - x;             // (u,v,w) is (X',Y',Z') in the text
  35.    w.normalize();
  36.    if(fabs(w.data[0]) >= fabs(w.data[1]))
  37.       { t.data[0] = 0.0; t.data[1] = 1.0; t.data[2] = 0.0; } 
  38.    else
  39.       { t.data[0] = 1.0; t.data[1] = 0.0; t.data[2] = 0.0; }
  40.    u = cross(w,t);
  41.    u.normalize();
  42.    v = cross(w,u);
  43.    v.normalize();
  44.    m.set_identity();
  45.    m.set_xyz_to_uvw(u,v,w);
  46.    psi = m * psi;
  47.    psi.normalize();
  48.    hit(x, psi, on_light);       // on_light is x" in the text
  49.    v1 = on_light - center;
  50.    v1.normalize();
  51.    v2 = x - on_light;
  52.    v2.normalize();
  53.    prob = dot(v1,v2) * 0.5 / 
  54.        (distance_squared(x,on_light) * PI * (1.0 - cos(theta_max))); 
  55. }
  56.